package cn.com.self.apis.core.enums;

import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.math.NumberUtils;

import java.util.HashSet;
import java.util.Set;

/**
 * 
 * @author tuhua yang
 *
 */
public enum JavaType {

	String, 
	Integer, 
	Long, 
	Float, 
	Double, 
	BigInteger, 
	BigDecimal, 
	Boolean, 
	LocalDateTime,
	LocalDate,
	LocalTime;
	
	public static boolean exists(String name) {
		return exists(name, false);
	}

	public static boolean exists(String name, boolean ignoreCase) {
		for (JavaType javaType: JavaType.values()) {
			if (ignoreCase) {
				if (javaType.name().equalsIgnoreCase(name)) {
					return true;
				}
			} else {
				if (javaType.name().equals(name)) {
					return true;
				}
			}
		}
		return false;
	}
	
	public static JavaType valueOf(String name, boolean ignoreCase) {
		try {
			return JavaType.valueOf(name);
		} catch (Exception e) {
			if (ignoreCase) {
				for (JavaType javaType: JavaType.values()) {
					if (javaType.name().equalsIgnoreCase(name)) {
						return javaType;
					}
				}
				throw new IllegalArgumentException("no enum constant JavaType." + name + ". Case insensitive.", e);
			}
			throw new IllegalArgumentException("no enum constant JavaType." + name + ". Case sensitive.", e);
		}
	}
	
	/**
	 * 把字符串化的值value解析为Java对象。例如，把字符串（"123"）解析成Integer（123），把字符串（"2016-08-31"）解析成Date
	 * 
	 * @param javaType		JavaType枚举名，如"Integer"
	 * @param value			字符串化的值，如"123"
	 * @return a {@link Object}.
	 * @throws	IllegalArgumentException  if the value cannot be converted
	 */
	public static Object parse(String javaType, String value) {
		return parse(javaType, value, false);
	}
	
	/**
	 * 把字符串化的值value解析为Java对象。例如，把字符串（"123"）解析成Integer（123），把字符串（"2016-08-31"）解析成Date
	 * 
	 * @param javaType		JavaType枚举名，如"Integer", "integer"
	 * @param value			字符串化的值，如"123"
	 * @param ignoreCase	是否对JavaType枚举名忽略大小写
	 * @return a {@link Object}.
	 * @throws	IllegalArgumentException  if the value cannot be converted
	 */
	public static Object parse(String javaType, String value, boolean ignoreCase) {
		return parse(valueOf(javaType, ignoreCase), value);
	}
	
	/**
	 * 把字符串化的值value解析为Java对象。例如，把字符串（"123"）解析成Integer（123），把字符串（"2016-08-31"）解析成Date
	 * 
	 * @param javaType		JavaType枚举值，如JavaType.Integer
	 * @param value			字符串化的值，如"123"
	 * @return a {@link Object}.
	 * @throws	IllegalArgumentException if the value cannot be converted
	 */
	public static Object parse(JavaType javaType, String value) {
		try {
			switch (javaType) {
				case Integer:
					return NumberUtils.createInteger(value);
				case Long:
					return NumberUtils.createLong(value);
				case Float:
					return NumberUtils.createFloat(value);
				case Double:
					return NumberUtils.createDouble(value);
				case BigInteger:
					return NumberUtils.createBigDecimal(value);
				case BigDecimal:
					return NumberUtils.createBigDecimal(value);
				case Boolean:
					return BooleanUtils.toBooleanObject(value);
				case LocalDateTime:
					return java.time.LocalDateTime.parse(value);
				case LocalDate:
					return java.time.LocalDate.parse(value);
				case LocalTime:
					return java.time.LocalTime.parse(value);
				default:
					return value;
			}
		} catch (Exception e) {
			throw new IllegalArgumentException(e);
		}
	}
	
	public static Set<String> stringify() {
		Set<String> names = new HashSet<String>();
		for (JavaType javaType: JavaType.values()) {
			names.add(javaType.name());
		}
		return names;
	}
	
}
